
<!--
  * emit('update:send', res)  用户语音
  * emit('update:receive', res)  机器人回复

  props:
  speaker  音色
  isPlay  是否播放
-->
<script setup lang="ts">
import { commonService } from '@/services/common.service';
import { Message } from '@arco-design/web-vue';
import { ref } from 'vue';
const props = withDefaults(defineProps<{ speaker: string, isPlay: boolean }>(), {
  speaker: 'alloy',
  isPlay: false
});

const emit = defineEmits(['update:send', 'update:receive'])
const isRecording = ref(false);
const isConvert = ref(false);

let mediaRecorder = null;
const maxTime = 60000; // 最大录音时长 ms
const currDuration = ref(0);  // 已录时长

function startRecording(): void {
  if (isRecording.value || isConvert.value) {
    return;
  }
  navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => {
    mediaRecorder = new MediaRecorder(stream);
    mediaRecorder.start();
    isRecording.value = true;
    // 录音结束时，停止并下载录音文件
    mediaRecorder.addEventListener("dataavailable", function (event) {
      isRecording.value = false;
      const file = new File([event.data], Date.now() + '.mp3', { type: "audio/mp3" });
      onConvert(file);
      currDuration.value = 0;
    });
    onStart();
  }).catch(err => {
    console.error('授权失败', err);
    Message.error('授权失败，请手动打开录音权限');
  })
}

function stopRecording(): void {
  mediaRecorder.stop();
  clearInterval(interval);
}

let interval = null;
function onStart(): void {
  interval = setInterval(() => {
    if (currDuration.value >= maxTime / 1000) {
      Message.warning("单次最长支持" + maxTime / 1000 + '秒');
      stopRecording();
    } else {
      currDuration.value++
    }
  }, 1000)
}

function onConvert(file: File): void {
  isConvert.value = true;
  const blob = new Blob([file], { type: "audio/mp3" });
  emit('update:send', { blob: blob, duration: currDuration.value })

  commonService.sts(file, props.speaker,
    (res => {
      isConvert.value = false;
      emit('update:receive', res)
    }),
    (err) => {
      console.log(err);
      isConvert.value = false
      console.log("问答失败，请再试一次吧")
    })
}

</script>
<template>
  <div class="sts">
    <div class="convert recording" v-if="isConvert">
      <icon-sync size="28" spin />
      <div class="post">
        <p class="desc">内容由gpt4.0生成</p>
      </div>
    </div>
    <div class="convert" v-else>
      <div class="recording flex" v-if="isRecording">
        <icon-record-stop @click="stopRecording" size="28" />
        <div class="post">
          <p class="desc">{{ currDuration }} / {{ maxTime / 1000 }}s</p>
          <p class="desc">内容由gpt4.0生成</p>
        </div>
      </div>
      <icon-voice v-else @click="startRecording" size="28" />
    </div>
  </div>
</template>
<style lang="scss" scoped>
.sts {
  cursor: pointer;
  background-color: var(--color-neutral-4);
  height: 60px;
  width: 60px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.convert {
  flex: 1;
  text-align: center;
  color: var(--color-text-2);
}

.recording {
  color: var(--color-text-2);
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;

  .post {
    width: 120px;
    position: absolute;
    top: 60px;
    left: -30px;
    text-align: center;
  }

  .desc {
    font-size: 12px;
    color: var(--color-text-3);
    margin-right: 4px;
    line-height: 22px;
  }
}
</style>
